/*
 * ******************************************************************************
 *   Copyright © 2013-2014 sean.yanghy. All rights reserved.
 *
 *  *****************************************************************************
 */

package com.exteam.common.network;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.util.DisplayMetrics;

import com.exteam.common.util.CommLogger;
import com.exteam.common.util.CommUtils;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * 工具
 *
 * @author sean.yanghy
 * @version v1.0
 * @created 2014-07-06 13:56:23
 */
public class NetworkUtils {

    public static String URLCacheDataPath = Environment
            .getExternalStorageDirectory().getPath() + "/water/cacheData/";

    /**
     * 处理请求的uri信息，移除部分变量字段
     */
    public static String formatURL(String url) {
        StringBuffer urlStr = new StringBuffer(url);
        int i = urlStr.indexOf("_t_");
        int j;
        if (i != -1) {
            // System.out.println(i);
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
            // System.out.println(urlStr.delete(i, j + 1));
        }

        i = urlStr.indexOf("_s_");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
            // System.out.println(urlStr.delete(i, j + 1));
        }
        i = urlStr.indexOf("ver");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
            // System.out.println(urlStr.delete(i, j + 1));
        }
        i = urlStr.indexOf("network");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
        }
        i = urlStr.indexOf("operator");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
        }
        // System.out.println(urlStr.delete(i, j + 1));
        return CommUtils.md5(urlStr.toString());
    }

    /**
     * 处理请求的uri信息，移除部分变量字段
     */
    public static String formatURL(String url, boolean isSetCookie) {
        StringBuffer urlStr = new StringBuffer(url);
        int i = urlStr.indexOf("_t_");
        int j;
        if (i != -1) {
            // System.out.println(i);
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
            // System.out.println(urlStr.delete(i, j + 1));
        }

        i = urlStr.indexOf("_s_");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
            // System.out.println(urlStr.delete(i, j + 1));
        }
        i = urlStr.indexOf("ver");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
            // System.out.println(urlStr.delete(i, j + 1));
        }
        i = urlStr.indexOf("network");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
        }
        i = urlStr.indexOf("operator");
        // System.out.println(i);
        if (i != -1) {
            if ((j = urlStr.indexOf("&", i)) != -1) {
                urlStr.delete(i, j + 1);
            } else {
                urlStr.delete(i, urlStr.length());
            }
        }
        if (isSetCookie) {
            urlStr.append(RequestManager.cookie);
        }
        // System.out.println(urlStr.delete(i, j + 1));
        return CommUtils.md5(urlStr.toString());
    }

    /**
     * 从本地读取文件，并返回字符串。
     */
    public static String readUrlCacheFromLocal(String fileName)
            throws Exception {
        File file = new File(URLCacheDataPath + fileName);
        InputStreamReader isr = new InputStreamReader(
                new FileInputStream(file), "utf-8");
        BufferedReader read = new BufferedReader(isr);
        // FileInputStream fis = new FileInputStream(file);
        int c;
        StringBuffer sb = new StringBuffer();
        while ((c = read.read()) != -1) {
            sb.append((char) c);
        }
        read.close();

        return sb.toString();
    }

    /**
     * 存储请求结果到本地。其中文件名 采用 经过 formatURL 方法处理的返回结果
     */
    public static void saveUrlCacheToLocal(final String filename,
                                           final String content) {
        new Thread() {
            public void run() {
                File filePath = null;
                try {
                    filePath = new File(URLCacheDataPath);
                    if (!filePath.exists()) {
                        CommLogger.d("testcache", filePath.mkdir() + " ");
                    }
                } catch (Exception e) {

                }
                File file = new File(filePath, filename);
                OutputStream out;
                try {
                    out = new FileOutputStream(file);
                    out.write(content.getBytes("utf-8"));
                    out.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                controlUrlCacheFilesSize(file);
            }
        }.start();

    }

    /**
     * 保存url数据
     *
     * @param filename
     * @param eTag
     * @param content
     */
    public static void saveUrlCacheToLocal(String filename, String eTag,
                                           String content) {
        if (eTag != null && content != null) {
            CommUtils.savePreference(filename, eTag);
            NetworkUtils.saveUrlCacheToLocal(filename, content);
        }
    }

    /**
     * 清楚缓存文件
     */
    public static void cleanrCaches() {
        CommUtils.deleteFile(new File(URLCacheDataPath));
    }

    private static int CACHEDATA_SIZE = 0;

    /*
     * 如果本地缓存的URL数据文件的大小大于10M的时候，按照最后的修改时间 删除 最旧的40%文件。
     * 如果返回true，提示本地缓存数据的大小大于等于10M，清除旧文件 成功 如果返回false，提示本地缓存的数据大小小于10M，不清楚旧文件
     */
    public static void controlUrlCacheFilesSize(final File file) {
        new Thread() {
            public void run() {
                File cacheFilesDir = new File(URLCacheDataPath);
                File[] cacheFiles = cacheFilesDir.listFiles();
                if (CACHEDATA_SIZE == 0) {
                    if (cacheFiles == null) {
                        return;
                    }
                    int dirSize = 0;
                    for (int i = 0; i < cacheFiles.length; i++) {
                        dirSize += cacheFiles[i].length();
                    }
                    CACHEDATA_SIZE = dirSize;
                } else {
                    if (file != null) {
                        CACHEDATA_SIZE = (int) (CACHEDATA_SIZE + file.length());
                        CommLogger.d("Youku", "cacheData after add file "
                                + CACHEDATA_SIZE);
                    }
                }
                if (CACHEDATA_SIZE >= 1024 * 1024 * 10) {
                    int removeFactor = (int) ((0.4 * cacheFiles.length) + 1);
                    System.setProperty("java.util.Arrays.useLegacyMergeSort",
                            "true");
                    try {
                        Arrays.sort(cacheFiles, new FileLastModifSort());
                    } catch (Exception e) {
                        CommLogger.e("NetworkUtils", e);
                    }
                    for (int i = 0; i < removeFactor; i++) {
                        cacheFiles[i].delete();
                    }
                    CACHEDATA_SIZE = 0;
                    controlUrlCacheFilesSize(null);
                }
            }
        }.start();

    }

    static class FileLastModifSort implements Comparator<File> {
        public int compare(File arg0, File arg1) {
            if (arg0.lastModified() > arg1.lastModified()) {
                return 1;
            } else if (arg0.lastModified() == arg1.lastModified()) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    public final static int NONE = 0; // 无网络
    public final static int WIFI = 1; // Wi-Fi
    public final static int MOBILE = 2; // 3G,GPRS
    public final static int CONN_TIMEOUT = 20000;
    public final static int READ_TIMEOUT = 20000;

    /**
     * 获取当前网络状态
     *
     * @param context
     * @return
     */
    public static int getNetworkState(Context context) {
        ConnectivityManager connManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        if (connManager == null) {
            return NONE;
        }

        NetworkInfo mobileInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        State state;
        if (mobileInfo != null) {
            // 手机网络判断
            state = mobileInfo.getState();
            if (state == State.CONNECTED || state == State.CONNECTING) {
                return MOBILE;
            }
        }

        if (wifiInfo != null) {
            // Wifi网络判断
            state = wifiInfo.getState();
            if (state == State.CONNECTED || state == State.CONNECTING) {
                return WIFI;
            }
        }


        return NONE;
    }

    /**
     * 判断get请求中，是否已经含有第一个参数，从而决定后续拼写参数的时候符号是什么
     *
     * @param url
     * @return
     */
    public static String getSymbol(String url) {
        int i = url.indexOf('?');
        if (i == -1) {
            return "?";
        } else {
            return "&";
        }
    }

    /**
     * 判断是否以http协议开头
     *
     * @return
     */
    public static boolean getHttp(String url) {
        return url.startsWith("http://");
    }

    /**
     * 获取分辨率
     */
    public static String getResolution(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels + "*" + dm.heightPixels;
    }

    /**
     * GET
     *
     * @param url
     * @return
     */
    public static String getJsonDataFromServerByGet(String url) throws IOException {
        String result = null;
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);
        HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), CONN_TIMEOUT); // 设置连接超时时间
        HttpConnectionParams.setSoTimeout(httpClient.getParams(), READ_TIMEOUT); // 设置数据读取超时时间
        HttpResponse response;
        try {
            response = (HttpResponse) httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == 200) {
                result = EntityUtils.toString(response.getEntity());
            } else {
                CommLogger.d("http error"
                        + response.getStatusLine().getStatusCode());
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            CommLogger.d(e.toString());
        }
        return result;
    }

    /**
     * @param httpClient
     * @param name
     * @param value
     */
    public static void setCookie(DefaultHttpClient httpClient, String name, String value) {
        Cookie cookie = new BasicClientCookie(name, value);
        Date date = new Date();

        //设置可访问Cookie的路径 为项目下的cookie文件夹及其子文件夹下所有页面
        //如果需要整个应用程序可访问 则设置为cookie.Path = "/"; 即可

        httpClient.getCookieStore().addCookie(cookie);
    }

    /**
     * @param httpClient
     * @return
     */
    public static String readCookieString(DefaultHttpClient httpClient) {
        List<Cookie> cookies = httpClient.getCookieStore().getCookies();

        StringBuffer tmpCookieStr = new StringBuffer();
        if (!cookies.isEmpty()) {
            Cookie cookie = null;
            for (int i = 0; i < cookies.size(); i++) {
                cookie = cookies.get(i);
                tmpCookieStr.append(cookie.getName()).append("=").append(cookie.getValue()).append("; ");
                tmpCookieStr.append("Domain=");
                tmpCookieStr.append(cookie.getDomain());
                tmpCookieStr.append(";");
                tmpCookieStr.append("Path=");
                tmpCookieStr.append(cookie.getPath());
                tmpCookieStr.append(";");
            }
        }
        return tmpCookieStr.toString();
    }

    /**
     * POST
     *
     * @param httpClient
     * @param url
     * @param params
     * @return
     */
    public static String getJsonDataFromServerByPost(DefaultHttpClient httpClient, String url, List<NameValuePair> params)
            throws IOException {

        String result = null;

        HttpPost requestPost = new HttpPost(url);
        HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), CONN_TIMEOUT); // 设置连接超时时间
        HttpConnectionParams.setSoTimeout(httpClient.getParams(), READ_TIMEOUT); // 设置数据读取超时时间

        HttpResponse response;
        // StringBuilder respond = new StringBuilder();

        try {
            requestPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
            response = (HttpResponse) httpClient.execute(requestPost);

            if (response.getStatusLine().getStatusCode() == 200) {
                result = EntityUtils.toString(response.getEntity());


            } else {
                CommLogger.e("http error"
                        + response.getStatusLine().getStatusCode());
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            CommLogger.e(e.toString());
        }

        // return respond.toString();
        return result;
    }

    /**
     * POST
     *
     * @param url
     * @param params
     * @return
     */
    public static String getJsonDataFromServerByPost(String url,
                                                     List<NameValuePair> params) throws IOException, ClientProtocolException {
        String result = null;
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), CONN_TIMEOUT); // 设置连接超时时间
        HttpConnectionParams.setSoTimeout(httpClient.getParams(), READ_TIMEOUT); // 设置数据读取超时时间

        HttpPost requestPost = new HttpPost(url);
        HttpResponse response;
        // StringBuilder respond = new StringBuilder();

        try {
            requestPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
            response = (HttpResponse) httpClient.execute(requestPost);

            if (response.getStatusLine().getStatusCode() == 200) {
                result = EntityUtils.toString(response.getEntity());

            } else {
                CommLogger.e("http error"
                        + response.getStatusLine().getStatusCode());
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            CommLogger.e(e.toString());
            throw e;
        }

        // return respond.toString();
        return result;
    }

    /**
     * GET
     *
     * @param urlString
     * @return
     */
    public static Bitmap getImageDataFromServerByGet(String urlString) throws IOException {
        //Drawable image = null;
        Bitmap bitmap = null;
        try {
            URL url = new URL(urlString);
            HttpURLConnection httpconn = (HttpURLConnection) url
                    .openConnection();
            httpconn.setConnectTimeout(CONN_TIMEOUT);
            httpconn.setReadTimeout(READ_TIMEOUT);
            InputStream is = httpconn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            return bitmap;
            //image = Drawable.createFromStream(is, "");
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            CommLogger.d(e.toString());
        }
        return bitmap;
    }

    /**
     * @param ctx
     * @return
     */
    public static String getLocalMacAddress(Context ctx) {
        WifiManager wifi = (WifiManager) ctx
                .getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifi.getConnectionInfo();
        return info.getMacAddress();
    }

    /**
     * @param blog
     * @return
     */
    public static Bitmap getBitmapFromIO(byte[] blog) {
        if (blog == null) {
            return null;
        }
        // Log.i(TAG, "blog.length" + blog.length);
        return BitmapFactory.decodeByteArray(blog, 0, blog.length);

    }

    /**
     * @param favicon
     * @return
     */
    public static byte[] getIOFromBitmap(Bitmap favicon) {
        if (favicon == null) {
            CommLogger.v("favicon is null");
            return null;
        }
        final ByteArrayOutputStream os = new ByteArrayOutputStream();
        favicon.compress(Bitmap.CompressFormat.PNG, 100, os);
        return os.toByteArray();
    }

}
